<template>
  <div class="config">
    <div class="editor-btn" @click="handleEdit">
      <el-icon><EditPen /></el-icon>
    </div>
    <el-form
        ref="ruleFormRef"
        label-width="120px"
        label-suffix=" :"
        :rules="rules"
        :disabled="isView"
        :model="configData"
        :hide-required-asterisk="isView"
    >
      <el-tabs class="config-tabs" @tabChange="handleTabChange">
        <el-tab-pane v-for="(configType, index) in configsByType" :label="configType.name">
          <template v-if="currentTab == index">
              <el-form-item v-for="configItem in configData" :label="configItem.name" :prop="`${configItem.code}['value']`">
                <FormItem :model-value="configItem" @update:modelValue="handleUpdateModelValue" />
              </el-form-item>
              <el-form-item>
                <el-button v-show="!isView" @click="cancel">取消</el-button>
                <el-button type="primary" v-show="!isView" @click="handleSubmit">确定</el-button>
              </el-form-item>
          </template>
        </el-tab-pane>
      </el-tabs>
    </el-form>
  </div>
</template>

<script lang="ts">
export default {
  name: "configSet",
}
</script>

<script setup lang="ts">
import { EditPen } from "@element-plus/icons-vue";
import {onMounted, reactive, ref} from "vue";
import { ElMessage, FormInstance } from "element-plus";
import {saveSysConfigsApi, sysConfigsByTypeApi} from "@/api/modules/config.ts";
import FormItem from "@/components/FormItem/index.vue";
import {Recordable} from "@/interface/types.ts";
import {isArray, isNumeric, isString} from "@/helper/is.ts";
import {dictValueListApi} from "@/api/modules/dict.ts";
import {authTreeApi} from "@/api/modules/auth.ts";
import {deptTreeCacheApi} from "@/api/modules/dept.ts";
import {cateTreeCacheApi} from "@/api/modules/cate.ts";

const currentTab = ref(0);
const isView = ref(true);
const configsByType = ref<any[]>([]);
const configData = ref<Recordable>({});
let rules = reactive<Recordable>({});

const cancel = () => {
  isView.value = true;
  ruleFormRef.value?.resetFields();
}

const handleEdit = () => {
  isView.value = false;
}

const dictValuesMap = ref<Recordable>({});
const authTree = ref<any[]>([]);
const deptTree = ref<any[]>([]);
const cateTree = ref<any[]>([]);
onMounted(() => {
  authTreeApi({}).then(res => {
    authTree.value = res.data as any[];
  })
  deptTreeCacheApi().then(res => {
    deptTree.value = res.data as any[];
  })
  cateTreeCacheApi().then(res => {
    cateTree.value = res.data as any[];
  })
  getConfigsByType();
})

const getConfigsByType = () => {
  sysConfigsByTypeApi({}).then(res => {
    configsByType.value = res.data as any[];
    initConfigData();
  })
}

const initConfigData = () => {
  configData.value = {};
  rules = {};
  if (configsByType.value && configsByType.value[currentTab.value].configs && configsByType.value[currentTab.value].configs.length) {
    configsByType.value[currentTab.value].configs.map((item: any) => {
      if (item.field_type == 2) {
        item.value = Number(item.value);
      } else if (item.field_type == 5) {
        item.value = item.value ? isArray(item.value) ? item.value : [item.value] : [];
      } else if (item.field_type == 7) {
        item.value = item.value ? item.value : '';
      } else {
        item.value += '';
      }
      if ([3, 4, 5, 6].indexOf(item.field_type) > -1) {
        getOptionValues(item);
      } else if (item.field_type == 7) {
        assembleDataSource(item);
      }
      configData.value[item.code] = item;
      rules[item.code + "['value']"] = [{ required: true, message: `${item.name}不能为空` }];
    });
  }
}

const getOptionValues = async (item: any) => {
  if (!item.option_value) {
    return;
  }
  if (item.option_type == 1) {
    let data = dictValuesMap.value[item.option_value];
    if (!data) {
      data = await dictValueListApi({dict_id: item.option_value});
    }
    assembleOptions(data, item);
  } else if (item.option_type == 2) {
    let jsonData = [];
    try {
      jsonData = JSON.parse(item.option_value);
    } catch (err) {
      console.error("预设选项值JSON格式异常：", err);
    }
    assembleOptions(jsonData, item);
  }
}

const assembleOptions = (optionValues: any[], item: any) => {
  item.options = [];
  optionValues.map(optionValue => {
    if (item.field_type == 3) {
      let flag = false;
      if (isNumeric(optionValue.value)) {
        flag = Boolean(Number(optionValue.value));
      } else if (isString(optionValue.value)) {
        flag = optionValue.value == 'true' ? true : optionValue.value == 'false' ? false : Boolean(optionValue.value);
      }
      if (flag) {
        item.active = optionValue.value;
        item.active_text = optionValue.name;
        item.active_icon = optionValue.code;
      } else {
        item.inactive = optionValue.value;
        item.inactive_text = optionValue.name;
        item.inactive_icon = optionValue.code;
      }
    } else {
      item.options.push({ name: optionValue.name, value: optionValue.value })
    }
  });
}

const assembleDataSource = (item: any) => {
  item.label = item.data_source == 1 ? "title" : "name";
  item.key = "id";
  item.treeData = item.data_source == 1 ? authTree.value : item.data_source == 2 ? deptTree.value : cateTree.value;
}

const handleTabChange = (tabIndex: number) => {
  currentTab.value = tabIndex;
  initConfigData();
}

const handleUpdateModelValue = (modelValue: any) => {
  configData.value[modelValue.code] = modelValue;
}

// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await saveSysConfigsApi({type: currentTab.value, configs: configData});
      ElMessage.success({ message: `保存系统配置成功！` });
      isView.value = true;
      ruleFormRef.value?.resetFields();
    } catch (error) {
      console.log(error);
    }
  });
};
</script>

<style scoped lang="scss">
.config {
  position: relative;
  height: 100%;
  background-color: var(--el-bg-color);
  .editor-btn {
    position: absolute;
    top: 30px;
    right: 18px;
    cursor: pointer;
    z-index: 1;
    opacity: 0.5;
    padding: 0 12px;
    &:hover {
      color: var(--el-color-primary);
      opacity: 1;
    }
  }
  .config-tabs {
    height: 100%;
    padding: 18px;
    border-radius: 4px;
    box-sizing: border-box;
    overflow: hidden;
  }
  :deep(.el-tabs) {
    .el-tabs__header {
      margin-bottom: 0;
      .custom-tabs-label > .el-icon {
        margin-right: 3px;
      }
    }
    .el-tabs__content {
      height: calc(100% - 75px);
      border-top: none;
      padding: 18px 12px;
    }
  }
  :deep(.upload-box) {
    .el-upload__tip {
      text-align: left;
    }
  }
}
</style>
